x86: Clean up TSC_RELIABLE handling after 20705:a74aca4b9386
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 19 Jan 2010 10:56:59 +0000 (10:56 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 19 Jan 2010 10:56:59 +0000 (10:56 +0000)
Set the feature by default and disable it if we can detect TSC warp,
rather than leaving the feature cleared and setting it if we happen
not to detect TSC warp.

This way round fixes dom0 kernel boot for Masaki Kanno.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/cpu/amd.c
xen/arch/x86/cpu/intel.c
xen/arch/x86/time.c
xen/include/asm-x86/cpufeature.h

index d7d3fe7cd7362917b255aea98429d1fbbea684ba..94f35770e5bd986bd4e9fa77979edf6a02da0ed2 100644 (file)
@@ -465,6 +465,8 @@ static void __devinit init_amd(struct cpuinfo_x86 *c)
                if (c->x86_power & (1<<8)) {
                        set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
                        set_bit(X86_FEATURE_NONSTOP_TSC, c->x86_capability);
+                       if (c->x86 != 0x11)
+                               set_bit(X86_FEATURE_TSC_RELIABLE, c->x86_capability);
                }
        }
 
index 0e5f6b8ac4cde9251c38fa464f69a5f5368d0d2c..5df0ec198fd8d21586687ec361a9fe40b8a1911a 100644 (file)
@@ -212,6 +212,7 @@ static void __devinit init_intel(struct cpuinfo_x86 *c)
        if (cpuid_edx(0x80000007) & (1u<<8)) {
                set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
                set_bit(X86_FEATURE_NONSTOP_TSC, c->x86_capability);
+               set_bit(X86_FEATURE_TSC_RELIABLE, c->x86_capability);
        }
        if ((c->cpuid_level >= 0x00000006) &&
            (cpuid_eax(0x00000006) & (1u<<2)))
index 292d797142462ee9ecd2abbe1c81a0888fcb3d91..3b814964b316e5335c922495af35811a429ac289 100644 (file)
@@ -1372,7 +1372,18 @@ void init_percpu_time(void)
 /* Late init function (after all CPUs are booted). */
 int __init init_xen_time(void)
 {
-    extern unsigned int max_cstate;
+    if ( boot_cpu_has(X86_FEATURE_TSC_RELIABLE) )
+    {
+        /*
+         * Sadly, despite processor vendors' best design guidance efforts, on
+         * some systems, cpus may come out of reset improperly synchronized.
+         * So we must verify there is no warp and we can't do that until all
+         * CPUs are booted.
+         */
+        tsc_check_reliability();
+        if ( tsc_max_warp )
+            setup_clear_cpu_cap(X86_FEATURE_TSC_RELIABLE);
+    }
 
     /* If we have constant-rate TSCs then scale factor can be shared. */
     if ( boot_cpu_has(X86_FEATURE_CONSTANT_TSC) )
@@ -1380,22 +1391,10 @@ int __init init_xen_time(void)
         int cpu;
         for_each_possible_cpu ( cpu )
             per_cpu(cpu_time, cpu).tsc_scale = per_cpu(cpu_time, 0).tsc_scale;
-    }
-    if ( (boot_cpu_has(X86_FEATURE_CONSTANT_TSC) && max_cstate <= 2) ||
-         boot_cpu_has(X86_FEATURE_NONSTOP_TSC) )
-    {
-        /*
-         * Sadly, despite processor vendors' best design guidance efforts,
-         * on some systems, cpus may come out of reset improperly
-         * synchronized.  So we must verify there is no warp and we
-         * can't do that until all CPUs are booted
-         */
-        tsc_check_reliability();
-        if ( tsc_max_warp == 0 )
-            set_boot_cpu_bit(X86_FEATURE_TSC_RELIABLE);
-    }
-    if ( !boot_cpu_has(X86_FEATURE_TSC_RELIABLE) )
+        /* If TSCs are not marked as 'reliable', re-sync during rendezvous. */
+        if ( !boot_cpu_has(X86_FEATURE_TSC_RELIABLE) )
             time_calibration_rendezvous_fn = time_calibration_tsc_rendezvous;
+    }
 
     open_softirq(TIME_CALIBRATE_SOFTIRQ, local_time_calibration);
 
@@ -1630,11 +1629,7 @@ void pv_soft_rdtsc(struct vcpu *v, struct cpu_user_regs *regs, int rdtscp)
 
 int host_tsc_is_safe(void)
 {
-    if ( boot_cpu_has(X86_FEATURE_TSC_RELIABLE) )
-        return 1;
-    if ( num_online_cpus() == 1 )
-        return 1;
-    return 0;
+    return boot_cpu_has(X86_FEATURE_TSC_RELIABLE) || (num_online_cpus() == 1);
 }
 
 void cpuid_time_leaf(uint32_t sub_idx, uint32_t *eax, uint32_t *ebx,
index d8bc61cf85d070d2a05055756eed45a03354a4c7..72fe0db491e7208b0a8ed2e97a34994913c2b7d1 100644 (file)
 
 #define cpu_has(c, bit)                test_bit(bit, (c)->x86_capability)
 #define boot_cpu_has(bit)      test_bit(bit, boot_cpu_data.x86_capability)
-#define set_boot_cpu_bit(bit)  set_bit(bit, boot_cpu_data.x86_capability)
 
 #ifdef __i386__
 #define cpu_has_vme            boot_cpu_has(X86_FEATURE_VME)